1 package org.apache.lucene.index;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.HashMap;
25 import java.util.IdentityHashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29
30 import org.apache.lucene.codecs.DocValuesProducer;
31 import org.apache.lucene.store.Directory;
32 import org.apache.lucene.util.Accountable;
33 import org.apache.lucene.util.Accountables;
34 import org.apache.lucene.util.Bits;
35 import org.apache.lucene.util.RamUsageEstimator;
36 import org.apache.lucene.util.Version;
37
38
39
40
41 class SegmentDocValuesProducer extends DocValuesProducer {
42
43 private static final long LONG_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(Long.class);
44 private static final long BASE_RAM_BYTES_USED =
45 RamUsageEstimator.shallowSizeOfInstance(SegmentDocValuesProducer.class);
46
47 final Map<String,DocValuesProducer> dvProducersByField = new HashMap<>();
48 final Set<DocValuesProducer> dvProducers = Collections.newSetFromMap(new IdentityHashMap<DocValuesProducer,Boolean>());
49 final List<Long> dvGens = new ArrayList<>();
50
51
52
53
54
55
56
57
58
59 SegmentDocValuesProducer(SegmentCommitInfo si, Directory dir, FieldInfos coreInfos, FieldInfos allInfos, SegmentDocValues segDocValues) throws IOException {
60 boolean success = false;
61 try {
62 Version ver = si.info.getVersion();
63 if (ver != null && ver.onOrAfter(Version.LUCENE_4_9_0)) {
64 DocValuesProducer baseProducer = null;
65 for (FieldInfo fi : allInfos) {
66 if (fi.getDocValuesType() == DocValuesType.NONE) {
67 continue;
68 }
69 long docValuesGen = fi.getDocValuesGen();
70 if (docValuesGen == -1) {
71 if (baseProducer == null) {
72
73 baseProducer = segDocValues.getDocValuesProducer(docValuesGen, si, dir, coreInfos);
74 dvGens.add(docValuesGen);
75 dvProducers.add(baseProducer);
76 }
77 dvProducersByField.put(fi.name, baseProducer);
78 } else {
79 assert !dvGens.contains(docValuesGen);
80
81 final DocValuesProducer dvp = segDocValues.getDocValuesProducer(docValuesGen, si, dir, new FieldInfos(new FieldInfo[] { fi }));
82 dvGens.add(docValuesGen);
83 dvProducers.add(dvp);
84 dvProducersByField.put(fi.name, dvp);
85 }
86 }
87 } else {
88
89
90
91 Map<Long,List<FieldInfo>> genInfos = new HashMap<>();
92 for (FieldInfo fi : allInfos) {
93 if (fi.getDocValuesType() == DocValuesType.NONE) {
94 continue;
95 }
96 List<FieldInfo> genFieldInfos = genInfos.get(fi.getDocValuesGen());
97 if (genFieldInfos == null) {
98 genFieldInfos = new ArrayList<>();
99 genInfos.put(fi.getDocValuesGen(), genFieldInfos);
100 }
101 genFieldInfos.add(fi);
102 }
103
104 for (Map.Entry<Long,List<FieldInfo>> e : genInfos.entrySet()) {
105 long docValuesGen = e.getKey();
106 List<FieldInfo> infos = e.getValue();
107 final DocValuesProducer dvp;
108 if (docValuesGen == -1) {
109
110
111 dvp = segDocValues.getDocValuesProducer(docValuesGen, si, dir, coreInfos);
112 } else {
113 dvp = segDocValues.getDocValuesProducer(docValuesGen, si, dir, new FieldInfos(infos.toArray(new FieldInfo[infos.size()])));
114 }
115 dvGens.add(docValuesGen);
116 dvProducers.add(dvp);
117 for (FieldInfo fi : infos) {
118 dvProducersByField.put(fi.name, dvp);
119 }
120 }
121 }
122 success = true;
123 } finally {
124 if (success == false) {
125 try {
126 segDocValues.decRef(dvGens);
127 } catch (Throwable t) {
128
129 }
130 }
131 }
132 }
133
134 @Override
135 public NumericDocValues getNumeric(FieldInfo field) throws IOException {
136 DocValuesProducer dvProducer = dvProducersByField.get(field.name);
137 assert dvProducer != null;
138 return dvProducer.getNumeric(field);
139 }
140
141 @Override
142 public BinaryDocValues getBinary(FieldInfo field) throws IOException {
143 DocValuesProducer dvProducer = dvProducersByField.get(field.name);
144 assert dvProducer != null;
145 return dvProducer.getBinary(field);
146 }
147
148 @Override
149 public SortedDocValues getSorted(FieldInfo field) throws IOException {
150 DocValuesProducer dvProducer = dvProducersByField.get(field.name);
151 assert dvProducer != null;
152 return dvProducer.getSorted(field);
153 }
154
155 @Override
156 public SortedNumericDocValues getSortedNumeric(FieldInfo field) throws IOException {
157 DocValuesProducer dvProducer = dvProducersByField.get(field.name);
158 assert dvProducer != null;
159 return dvProducer.getSortedNumeric(field);
160 }
161
162 @Override
163 public SortedSetDocValues getSortedSet(FieldInfo field) throws IOException {
164 DocValuesProducer dvProducer = dvProducersByField.get(field.name);
165 assert dvProducer != null;
166 return dvProducer.getSortedSet(field);
167 }
168
169 @Override
170 public Bits getDocsWithField(FieldInfo field) throws IOException {
171 DocValuesProducer dvProducer = dvProducersByField.get(field.name);
172 assert dvProducer != null;
173 return dvProducer.getDocsWithField(field);
174 }
175
176 @Override
177 public void checkIntegrity() throws IOException {
178 for (DocValuesProducer producer : dvProducers) {
179 producer.checkIntegrity();
180 }
181 }
182
183 @Override
184 public void close() throws IOException {
185 throw new UnsupportedOperationException();
186 }
187
188 @Override
189 public long ramBytesUsed() {
190 long ramBytesUsed = BASE_RAM_BYTES_USED;
191 ramBytesUsed += dvGens.size() * LONG_RAM_BYTES_USED;
192 ramBytesUsed += dvProducers.size() * RamUsageEstimator.NUM_BYTES_OBJECT_REF;
193 ramBytesUsed += dvProducersByField.size() * 2 * RamUsageEstimator.NUM_BYTES_OBJECT_REF;
194 for (DocValuesProducer producer : dvProducers) {
195 ramBytesUsed += producer.ramBytesUsed();
196 }
197 return ramBytesUsed;
198 }
199
200 @Override
201 public Collection<Accountable> getChildResources() {
202 final List<Accountable> resources = new ArrayList<>(dvProducers.size());
203 for (Accountable producer : dvProducers) {
204 resources.add(Accountables.namedAccountable("delegate", producer));
205 }
206 return Collections.unmodifiableList(resources);
207 }
208
209 @Override
210 public String toString() {
211 return getClass().getSimpleName() + "(producers=" + dvProducers.size() + ")";
212 }
213 }